<html>
	<head>
		<title>Using MINA Filters with QFJ</title>
		<link href="../style.css" rel="stylesheet" type="text/css"/>
	</head>
<body>
<div class="header">
<h1>QuickFIX/J User Manual</h1>
</div>
<h2>Using MINA Filters</h2>
<p>Adding a custom MINA IO Filter allows you to inspect and manipulate:</p>
<ul>
<li>Network events such as connects and disconnects,</li>
<li>FIX messages after they are sent by the QuickFIX/J engine but before they are sent on the network, and</li>
<li>FIX messages after they are received from the network but before they are processed by the QuickFIX/J engine.</li>
</ul>

<p>MINA's javadoc for <code><a href="http://mina.apache.org/report/1.1/apidocs/org/apache/mina/common/IoFilter.html">IoFilter</a></code>
gives some examples of how this could be useful:
<blockquote>
<ul>
<li>Event logging</li>
<li>Performance measurement</li>
<li>Authorization</li>
<li>Overload control</li>
<li>Message transformation (e.g. encryption and decryption, ...)</li>
</ul>
</blockquote>

<p>To add a filter, you need to insert it into the filter chain by supplying an IoFilterChainBuilder to
 the connector or acceptor with setIoFilterChainBuilder().
</p>
<pre class="code">
final BlacklistFilter blacklistFilter = new BlacklistFilter();
...
 /*
  * setIoFilterChainBuilder is defined on the SessionConnector abstract class
  */
((SessionConnector) acceptor).setIoFilterChainBuilder(new IoFilterChainBuilder() {

    public void buildFilterChain(IoFilterChain chain) {
        chain.addBefore(FIXProtocolCodecFactory.FILTER_NAME, "BlacklistFilter", blacklistFilter);
    }});
</pre>

<p>Note the reference to FIXProtocolCodecFactory.FILTER_NAME.  QuickFIX/J uses a ProtocolCodecFilter
to transform between streamed byte data on the wire and quickfix.Message objects, as shown below.
</p>

<img src="protocol codec filter.png"/>

<p>You should add your filter before this one to have it act on the byte stream, or after it to act on
quickfix.Message data.</p>
<p>Following are some examples showing how to add filters to the example order executor application</p>

<hr/>
<h3>Blacklist Filter</h3>
<p>
MINA comes with a Blacklist filter which closes incoming connections from blacklisted addresses.
Lets add this filter to the order executor and make it block connections from localhost. We will add it
before the protocol codec filter.
</p>
<img src='blacklist filter.png'/>
<p>To do this, change:</p>

<pre class="code">
acceptor = new SocketAcceptor (application, messageStoreFactory, settings, logFactory, messageFactory);
acceptor.start();
</pre>

<p>to this (plus the appropriate imports):</p>

<pre class="code">
acceptor = new SocketAcceptor (application, messageStoreFactory, settings, logFactory, messageFactory);

/* create the filter and add an address to the blacklist */
final BlacklistFilter blacklistFilter = new BlacklistFilter();

blacklistFilter.block(InetAddress.getByName("localhost"));

/* add it to the acceptor */
((SessionConnector) acceptor).setIoFilterChainBuilder(new IoFilterChainBuilder() {

    public void buildFilterChain(IoFilterChain chain) {
        chain.addBefore(FIXProtocolCodecFactory.FILTER_NAME, "BlacklistFilter", blacklistFilter);
    }});
acceptor.start();
</pre>
<p>
Now when you start the executor and banzai apps you'll see this:
</p>
<b style="color=#404080">Executor Log</b>
<pre class="code">
&lt;20060913-10:54:22, FIX.4.2:EXEC-&gt;BANZAI, event&gt; (Session FIX.4.2:EXEC-&gt;BANZAI schedule is daily, 00:00:00 UTC - 00:00:00 UTC)
&lt;20060913-10:54:22, FIX.4.2:EXEC-&gt;BANZAI, event&gt; (Valid order types: [F, 2])
&lt;20060913-10:54:22, FIX.4.2:EXEC-&gt;BANZAI, event&gt; (Created session: FIX.4.2:EXEC-&gt;BANZAI)
13/09/2006 20:54:22 quickfix.mina.acceptor.AbstractSocketAcceptor startAcceptingConnections
INFO: Listening for connections at 0.0.0.0/0.0.0.0:9876
press &lt;enter&gt; to quit
13/09/2006 20:54:26 quickfix.mina.acceptor.AcceptorIoHandler sessionCreated
INFO: MINA session created: /127.0.0.1:4538
13/09/2006 20:54:26 org.apache.mina.util.SessionLog info
INFO: [/127.0.0.1:4538] Remote address in the blacklist; closing.
13/09/2006 20:54:26 org.apache.mina.util.SessionLog info
INFO: [/127.0.0.1:4538] Remote address in the blacklist; closing.
</pre>

<p/>
<b style="color=#404080">Banzai Log</b>
<pre class="code">
&lt;20060913-10:54:26, FIX.4.2:BANZAI-&gt;EXEC, event&gt; (Session FIX.4.2:BANZAI-&gt;EXEC schedule is daily, 00:00:00 UTC - 00:00:00 UTC)
&lt;20060913-10:54:26, FIX.4.2:BANZAI-&gt;EXEC, event&gt; (Created session: FIX.4.2:BANZAI-&gt;EXEC)
&lt;20060913-10:54:26, FIX.4.2:BANZAI-&gt;EXEC, outgoing&gt; (8=FIX.4.29=6535=A34=449=BANZAI52=20060913-10:54:26.75056=EXEC98=0108=3010=223)
&lt;20060913-10:54:26, FIX.4.2:BANZAI-&gt;EXEC, event&gt; (Initiated logon request)
&lt;20060913-10:54:26, FIX.4.2:BANZAI-&gt;EXEC, event&gt; (Disconnecting)
13/09/2006 20:54:26 quickfix.mina.initiator.InitiatorIoHandler sessionCreated
INFO: MINA session created: /127.0.0.1:4538
</pre>

<hr/>
<h3>Whitelist Filter</h3>
<p>A whitelist filter is available at <a href='http://www.quickfixj.org/confluence/download/attachments/530/WhitelistFilter.java'>
http://www.quickfixj.org/confluence/download/attachments/530/WhitelistFilter.java</a>.
The code changes required to use it are similar to the Blacklist filter, except that:</p>
<ul>
<li>The filter is configured from SessionSettings.</li>
<li>You have to add the filter after FIXProtocolCodecFactory.FILTER_NAME as the filter needs to see
quickfix.Message object, not just a stream of bytes.</li>
</ul>
<p/>
<img src='whitelist filter.png'/>

<pre class="code">
acceptor = new SocketAcceptor (application, messageStoreFactory, settings, logFactory, messageFactory);

final WhitelistFilter whitelistFilter = new WhitelistFilter(settings);
((SessionConnector) acceptor).setIoFilterChainBuilder(new IoFilterChainBuilder() {
    public void buildFilterChain(IoFilterChain chain) {
        chain.addAfter(FIXProtocolCodecFactory.FILTER_NAME, "WhitelistFilter", whitelistFilter);
    }});

acceptor.start();
</pre>
<p>
Specify valid IP addresses with the WhitelistHost setting, at either the default
or session levels as required.
</p>
<pre class="code">
[default]
...
WhitelistHost=www.quickfixj.org

[session]
SenderCompID=EXEC
TargetCompID=BANZAI

[session]
SenderCompID=EXEC
TargetCompID=SONOFBANZAI
WhitelistHost1=127.0.0.1
WhitelistHost2=192.168.0.1, 192.168.0.2

[session]
SenderCompID=EXEC
TargetCompID=FREEFORALL
WhitelistHost=
</pre>

<p>
On startup the valid hosts will be logged:
</p>
<pre class="code">
INFO: Authorised IPs for FIX.4.2:EXEC-&gt;FREEFORALL: [Any]
INFO: Authorised IPs for FIX.4.2:EXEC-&gt;BANZAI: [www.quickfixj.org/213.246.61.101]
INFO: Authorised IPs for FIX.4.2:EXEC-&gt;SONOFBANZAI: [/192.168.0.1, /127.0.0.1, www.quickfixj.org/213.246.61.101, /192.168.0.2]
</pre>
<p>
New connections will be validated against the authorised IPs once the first message is received and closed if they are not valid:
</p>
<pre class="code">
WARNING: [/127.0.0.1:2633] Closing FIX.4.2:EXEC-&gt;BANZAI connection from unauthorised address.
</pre>

</body>
</html>
